﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace urBook.Engine
{
    /// <summary>
    /// Object representation of person name in ContactCard class
    /// </summary>
    public class Name : ICloneable
    {
        [XmlElement("first")]
        public string firstName { get; set; }
        [XmlElement("last")]
        public string lastName { get; set; }

        public string formattedName { get {
            String result = "";
            if (firstName != null && firstName != "")
                result += firstName + " ";
            result += lastName;
            return result; 
        } }

        public override string ToString()
        {
            return firstName + " " + lastName;
        }

        public string toVcfString()
        {
            return "N:" + lastName + ";" + firstName + "\n" + 
                   "FN:" + formattedName + "\n";
        }

        public string toXmlString()
        {
            return "<Name>" +
                   "<firstName>" + firstName + "</firstName>" +
                   "<lastName>" + lastName + "</lastName>" +
                   "</Name>";
        }

        public object Clone()
        {
            return new Name() { firstName = this.firstName, lastName = this.lastName };
        }
    }
    public abstract class Item : ICloneable
    {
        [XmlAttribute("type")]
        public Type type { get; set; }
        [XmlElement("value")]
        public string value { get; set; }
        [XmlAttribute(AttributeName = "prefered", DataType = "boolean")]
        public bool isPreferred { get; set; }

        public Item()
        {
            type = Type.OTHER;
            value = "";
            isPreferred = false;
        }

        public abstract string toVcfString();

        public override string ToString()
        {
            return type + ": " + value;
        }

        public object Clone()
        {
            if (this is Telephone)
                return new Telephone() { type = this.type, value = this.value, isPreferred = this.isPreferred };
            else if (this is Email)
                return new Email() { type = this.type, value = this.value, isPreferred = this.isPreferred };
            else return null;
        }
    }
    public class Telephone : Item, ICloneable
    {
        /*
        public Telephone()
        {
            type = Type.CELL;
            isPreferred = false;
            phoneNumber = "";
        }
        [XmlAttribute("type")]
        public Type type { get; set; }
        [XmlElement("phone")]
        public string phoneNumber { get; set; }
        [XmlAttribute(AttributeName="prefered", DataType="boolean")]
        public bool isPreferred { get; set; }

        public override string ToString()
        {
            return type + ": " + value;
        }
        */

        public override string toVcfString()
        {
            return "TEL;" + type + ";" + (isPreferred ? "PREF;" : "") + "VOICE:" + value + "\n";
        }
        /*
        public string toXmlString()
        {
            return "<Telephone type=\"" + type + "\" preferred=\"" + isPreferred + "\">" + 
                   value + 
                   "</Telephone>";
        }
        
        public object Clone()
        {
            return new Telephone() { type = this.type, value = this.value, isPreferred = this.isPreferred };
        }*/
    }
    public class Address : ICloneable
    {
        [XmlAttribute("type")]
        public Type type { get; set; }
        [XmlElement("street")]
        public string street { get; set; }
        [XmlElement("city")]
        public string city { get; set; }
        [XmlElement("state")]
        public string state { get; set; }
        [XmlElement("postalCode")]
        public string postalCode { get; set; }
        [XmlElement("country")]
        public string country { get; set; }

        public override string ToString()
        {
            return type + ": " + street + "\n" + city + ", " + state + " " + postalCode + "\n" + country;
        }

        public string toVcfString()
        {
            return "ADR;" + type + ":"+ ";" + ";" + street + ";" + city + ";" + state + ";" + postalCode + ";" + country + "\n" + 
                   "LABEL;" + type + ":" + street + ", " + city + ", " + state + ", " + postalCode + ", " + country + "\n";
        }
        /*
        public string toXmlString()
        {
            return "<Address type=\"" + type + "\">" +
                   "<street>" + street + "</street>" + 
                   "<city>" + city + "</city>" +
                   "<state>" + state + "</state>" +
                   "<postalCode>" + postalCode + "</postalCode>" +
                   "<country>" + country + "</country>" +
                   "</Address>";
        }
        */
        public object Clone()
        {
            return new Address() { city = this.city, country = this.country, state = this.state, postalCode = this.postalCode, street = this.street, type = this.type };
        }
    }
    public class Email : Item, ICloneable
    {
        /*
        public Email()
        {
            type = Type.INTERNET;
            isPreferred = false;
            email = "";
        }

        [XmlAttribute("type")]
        public Type type { get; set; }
        [XmlElement("email")]
        public string email { get; set; }
        [XmlAttribute(AttributeName = "prefered", DataType = "boolean")]
        public bool isPreferred { get; set; }
        
        public override string ToString()
        {
            return type + ": " + value;
        }
        */

        public override string toVcfString()
        {
            return "EMAIL;" + (isPreferred ? "PREF;" : ";") + type + ":" + value + "\n";
        }
        /*
        public string toXmlString()
        {
            return "<Email type=\"" + type + "\" preferred=\"" + isPreferred + "\">" + 
                   value + 
                   "</Email>";
        }

        public object Clone()
        {
            return new Email() { type = this.type, email = this.email, isPreferred = this.isPreferred };
        }*/
    }
    [XmlInclude(typeof(EmbeddedPhoto))]
    public class Photo : ICloneable
    {
        public Photo()
        {
            value = Type.URL;
            ext = "";
            url = "";
        }

        [XmlAttribute("value")]
        public Type value { get; set; }
        [XmlAttribute("type")]
        public string ext { get; set; }
        [XmlAttribute("url")]
        public string url { get; set; }

        public override string ToString()
        {
            return "Photo: " + value + ": " + url;
        }

        public virtual string toVcfString()
        {
            return "PHOTO;VALUE=" + value + ";TYPE=" + ext + ":" + url + "\n";
        }

        public virtual string toXmlString()
        {
            return "<Photo value=\"" + value + "\" type=\"" + ext + "\">" + 
                   url + 
                   "</Photo>";
        }

        public object Clone()
        {
            return new Photo() { value = this.value, url = this.url, ext = this.ext };
        }
    }
    public class EmbeddedPhoto : Photo, ICloneable
    {
        public EmbeddedPhoto()
        {
            value = Type.EMBEDDED;
            encoding = "BASE64";
            ext = "JPEG";
            imageBuffer = "";
        }

        [XmlAttribute("encoding")]
        public string encoding { get; set; }
        [XmlElement("data")]
        public string imageBuffer { get; set; }

        public override string ToString()
        {
            return value + "(" + ext + "/" + encoding + "): " + imageBuffer;
        }

        public override string toVcfString()
        {
            return "PHOTO;TYPE=" + ext + ";ENCODING=" + encoding + ":" + 
                "\n" + imageBuffer + "\n";
        }

        public override string toXmlString()
        {
            return "<Photo value=\"" + value + "\" type=\"" + ext + "\" encoding=\"" + encoding + "\">" +
                   imageBuffer +
                   "</Photo>";
        }

        public object Clone()
        {
            return new EmbeddedPhoto() { encoding = this.encoding, imageBuffer = this.imageBuffer, value = this.value, url = this.url, ext = this.ext };
        }
    }

    public enum Type
    {
        HOME,
        CELL,
        WORK,
        FAX,
        OTHER,
        INTERNET,
        URL, 
        EMBEDDED
    };
}
